package serviceset1.restTemplate

import com.netflix.config.ConfigurationManager
import com.netflix.hystrix.Hystrix
import com.netflix.hystrix.HystrixCircuitBreaker
import com.netflix.hystrix.HystrixCommandKey
import com.netflix.hystrix.HystrixCommandMetrics
import grails.gorm.transactions.Rollback
import grails.testing.mixin.integration.Integration
import org.springframework.beans.factory.annotation.Autowired
import spock.lang.Specification

@Integration
@Rollback
class ServiceSet2ProxyServiceSpec extends Specification{

    private static final CommandKey = "ServiceSet2ProxyService#sampleApi2(String)"

    @Autowired
    private ServiceSet2ProxyService serviceSet2ProxyService

    def setupSpec() {
        Hystrix.reset()
    }

    def setup() {
    }

    def cleanup() {
    }

    void "test fallbackMethod"() {
        given:
            def dependency = "restTemplate"

        when: "The circuit breaker is open when call the method 'process'."
            def result = serviceSet2ProxyService.sampleApi2(dependency)

        then:
            result instanceof Map
            result.state == "offline"
            result.provider == "sampleApi2@serviceSet2"
            result.dependency == dependency
    }

    void "shouldTripCircuit"() {
        given:
            ConfigurationManager.getConfigInstance().setProperty("hystrix.command.${CommandKey}.circuitBreaker.requestVolumeThreshold", 1)
            HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory.getInstance(HystrixCommandKey.Factory.asKey(CommandKey))

        when: "nothing to do"

        // demonstrates circuit is actually closed
        then:
            !circuitBreaker.isOpen()
            circuitBreaker.allowRequest()

        when:
            serviceSet2ProxyService.sampleApi2("restTemplate")

        and:
            /*
            waitUntilCircuitBreakerOpens
            one second is almost sufficient
            borrowed from https://github.com/Netflix/Hystrix/blob/v1.5.5/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCircuitBreakerTest.java#L140
             */
            sleep 1000

        then:
            circuitBreaker.isOpen()
            !circuitBreaker.allowRequest()
    }

    void "shouldHaveCustomTimeout"() {
        expect: "Check timeoutInMilliseconds flow the custom by @HystrixCommand.commandProperties or default configuration"
            HystrixCommandMetrics.getInstance(HystrixCommandKey.Factory.asKey(CommandKey)).getProperties().executionTimeoutInMilliseconds().get() == 12000
    }
}
